﻿using System.Xml;

namespace Main.Structure
{
    /// <summary>
    /// This class contains all of the data of an assigned client.
    /// </summary>
    public class Client
    {
        // Local variables:
        private string _city, _firstName, _lastName, _phone, _notes, _state, _street, _zip;
        private uint _accountid;
        private object _syncObject = new object(); // Object used to prevent cross-threading.

        /// <summary>
        /// Class Constructor.
        /// Takes the passed parameter and assigns the AccountID with that value.
        /// </summary>
        /// <param name="id">The value of the client's AccountID.</param>
        public Client(uint id)
        {
            _accountid = id;
        }

        /// <summary>The client's account ID. Value retrieval only.</summary>
        public uint AccountID
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _accountid;
            }
        }

        /// <summary>The client's registered city.</summary>
        public string City
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _city;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _city = value;
            }
        }

        /// <summary>The client's registered first name.</summary>
        public string FirstName
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _firstName;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _firstName = value;
            }
        }

        /// <summary>The client's registered last name.</summary>
        public string LastName
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _lastName;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _lastName = value;
            }
        }

        /// <summary>Combination of the client's registered first and last name. Value retrieval only.</summary>
        public string Name
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _firstName + " " + _lastName;
            }
        }

        /// <summary>The client's registered phone number.</summary>
        public string Phone
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _phone;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _phone = value;
            }
        }

        /// <summary>Any administrator notes associated with this client's account.</summary>
        public string Notes
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _notes;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _notes = value;
            }
        }

        /// <summary>The client's registered state.</summary>
        public string State
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _state;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _state = value;
            }
        }

        /// <summary>The client's registered street.</summary>
        public string Street
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _street;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _street = value;
            }
        }

        /// <summary>The client's registered zipcode.</summary>
        public string Zip
        {
            get
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    return _zip;
            }
            set
            {
                lock (_syncObject) // Lock this object so nothing else is happening with this class.
                    _zip = value;
            }
        }

        /// <summary>This method is used to make changes to a client's information and then saves it.</summary>
        /// <param name="section">What node is being changed.</param>
        /// <param name="data">The value to assign to that node.</param>
        public void Edit(string section, string data)
        {
            lock (_syncObject)
            {
                XmlDocument xDoc = new XmlDocument(); // XmlDocument is used to read/write to/from XML documents.
                xDoc.Load(Hub.Configuration.CLIENT_PATH + _accountid.ToString() + ".xml"); // Load the client's account file.
                xDoc.SelectSingleNode("Client/" + section).InnerText = data; // Change the data in the specified node.
                xDoc.Save(Hub.Configuration.CLIENT_PATH + _accountid.ToString() + ".xml"); // Save any changes.
            }
        }

        /// <summary>This method edits the client's file to whatever the current values are for the client information.</summary>
        public void EditAll()
        {
            lock (_syncObject)
            {
                XmlDocument xDoc = new XmlDocument(); // XmlDocument is used to read/write to/from XML documents.
                xDoc.Load(Hub.Configuration.CLIENT_PATH + _accountid.ToString() + ".xml"); // Load the client's account file.
                xDoc.SelectSingleNode("Client/FirstName").InnerText = _firstName; // Change the data in the specified node.
                xDoc.SelectSingleNode("Client/LastName").InnerText = _lastName;
                xDoc.SelectSingleNode("Client/Address/Street").InnerText = _street;
                xDoc.SelectSingleNode("Client/Address/City").InnerText = _city;
                xDoc.SelectSingleNode("Client/Address/State").InnerText = _state;
                xDoc.SelectSingleNode("Client/Address/Zip").InnerText = _zip;
                xDoc.SelectSingleNode("Client/Phone").InnerText = _phone;
                xDoc.SelectSingleNode("Client/Notes").InnerText = _notes;
                xDoc.Save(Hub.Configuration.CLIENT_PATH + _accountid.ToString() + ".xml"); // Save any changes.
            }
        }

        /// <summary>This methods sets all data fields to "EMPTY" to symbolize this client no longer exists.</summary>
        public void Wipe()
        {
            lock (_syncObject)
            {
                _firstName = "EMPTY";
                _lastName = "EMPTY";
                _street = "EMPTY";
                _city = "EMPTY";
                _state = "EMPTY";
                _zip = "EMPTY";
                _phone = "EMPTY";
                _zip = "EMPTY";
                EditAll();
            }
        }
    }
}
